/*
    Copyright (c);2019-2022;Wiscom System;

	All rights reserved.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    3. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    3. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the Wiscom System nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include "los_base.h"
#include "los_task.h"
#include "los_hwi.h"
#include "los_typedef.h"
#include "pcrambox.h"
#include "los_api_tlsf.h"
#include "los_inspect_entry.h"
#include "ff.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
#define PCRAM_BOX_HEAD_SIZE 0x60a8
static UINT32 *p_buf[10];
static UINT32 g_TestTaskID01;
static UINT32 g_TestTaskID02;
static LOS_PCRAMBOX_INFO *pstBoxInfo;
static VOID Example_pcramBOX_malloc_Task1(VOID)
{
    UINT32 *uwRet = NULL;
    VIB *curVIB[2] = {NULL};
    UINT32 TID;
    
    UINT32 *flag, test_n,i,j;
    test_n=1;
    flag=&test_n;
    *flag = 1;
    char name[] = "billx";
    char Temp_Identifier[8]={0};
	/* mem alloc */
    for(i=0;i<2;i++)
    {
        name[4]=0x30+i;
        uwRet=SC_MALLOC(name,16, flag);
        if(uwRet == NULL)
        {
            printf("4. Task1: SC_MALLOC '%s' failed!\r\n", name);
            printf("4. Task1: pstBoxInfo->uwBlkCnt is %d !\r\n", pstBoxInfo->uwBlkCnt);
            // printf("4. Task1: pstBoxInfo->uwBlkSize is %d Bytes,pstBoxInfo->uwBlkNum is %d!\r\n",pstBoxInfo->uwBlkSize,pstBoxInfo->uwBlkNum);
            printf("4. Task1: uwRet is 0x%x\r\n", uwRet);
        }
        else
        {
            printf("4. Task1: SC_MALLOC '%s' success!\r\n", name);
            printf("4. Task1: pstBoxInfo->uwBlkCnt is %d !\r\n", pstBoxInfo->uwBlkCnt);
            // printf("4. Task1: pstBoxInfo->uwBlkSize is %d Bytes,pstBoxInfo->uwBlkNum is %d!\r\n",pstBoxInfo->uwBlkSize,pstBoxInfo->uwBlkNum);
            TID = (UINT32)LOS_CurTaskIDGet();
            printf("4. Task1: uwRet is 0x%x, TID is %d. \r\n", uwRet,TID);
            curVIB[i]=osFoundVIB(TID, name);
            printf("4. Task1: '%s' varBlkNum is %d, addrStart is 0x%x\r\n", name,curVIB[i]->varBlkNum,curVIB[i]->addrStart);
        }
        printf("\r\n");

    }
    
	for(i=0; i<2; i++)
	{	
        p_buf[i]=curVIB[i]->addrStart;
        EXMC_PCRAM_BufferRead(Temp_Identifier,curVIB[i]->varName.Identifier,8);
        dprintf("5. Task1: write '%s(TID is %d)':\r\n", Temp_Identifier,curVIB[i]->varName.TID);
		for(j=0; (j*4)<((curVIB[i]->varBlkNum)*(pstBoxInfo->uwBlkSize)); j++)
		{
	        p_buf[i][j] = (i+1)*j+7;
			dprintf("4. Task1: write pbuf[%d][%d] 0x%x = %d\r\n", i,j, &p_buf[i][j], (i+1)*j+7);
		}
	}
    LOS_TaskDelay(500);
	for(i=0; i<2; i++)
	{	
        p_buf[i]=curVIB[i]->addrStart;
        EXMC_PCRAM_BufferRead(Temp_Identifier,curVIB[i]->varName.Identifier,8);
        dprintf("5. Task1: read '%s(TID is %d)':\r\n", Temp_Identifier,curVIB[i]->varName.TID);
		for(j=0; (j*4)<((curVIB[i]->varBlkNum)*(pstBoxInfo->uwBlkSize)); j++)
		{
			dprintf("4. Task1: read pbuf[%d][%d] 0x%x = %d\r\n", i,j, &p_buf[i][j], p_buf[i][j]);
		}
	}
    dprintf("4. Task1 EXIT!\r\n");
    LOS_TaskDelay(1000);
}
static VOID Example_pcramBOX_malloc_Task2(VOID)
{
    UINT32 *uwRet = NULL;
    VIB *curVIB[2] = {NULL};
    UINT32 TID;
    
    UINT32 *flag, test_n,i,j;
    test_n=1;
    flag=&test_n;
    *flag = 1;
    char name[] = "billx";
    char Temp_Identifier[8]={0};
	/* mem alloc */
    for(i=0;i<2;i++)
    {
        name[4]=0x30+i;
        uwRet=SC_MALLOC(name,16, flag);
        if(uwRet == NULL)
        {
            printf("5. Task2: SC_MALLOC '%s' failed!\r\n", name);
            printf("5. Task2: pstBoxInfo->uwBlkCnt is %d !\r\n", pstBoxInfo->uwBlkCnt);
            // printf("5. Task2: pstBoxInfo->uwBlkSize is %d Bytes,pstBoxInfo->uwBlkNum is %d!\r\n",pstBoxInfo->uwBlkSize,pstBoxInfo->uwBlkNum);
            printf("5. Task2: uwRet is 0x%x\r\n", uwRet);
        }
        else
        {
            printf("5. Task2: SC_MALLOC '%s' success!\r\n", name);
            printf("5. Task2: pstBoxInfo->uwBlkCnt is %d !\r\n", pstBoxInfo->uwBlkCnt);
            // printf("5. Task2: pstBoxInfo->uwBlkSize is %d Bytes,pstBoxInfo->uwBlkNum is %d!\r\n",pstBoxInfo->uwBlkSize,pstBoxInfo->uwBlkNum);
            TID = (UINT32)LOS_CurTaskIDGet();
            printf("5. Task2: uwRet is 0x%x, TID is %d. \r\n", uwRet,TID);
            curVIB[i]=osFoundVIB(TID, name);
            printf("5. Task2: '%s' varBlkNum is %d, addrStart is 0x%x\r\n", name,curVIB[i]->varBlkNum,curVIB[i]->addrStart);
        }
        printf("\r\n");

    }
	for(i=0; i<2; i++)
	{	
        p_buf[i]=curVIB[i]->addrStart;
        EXMC_PCRAM_BufferRead(Temp_Identifier,curVIB[i]->varName.Identifier,8);
        dprintf("5. Task2: write '%s(TID is %d)':\r\n", Temp_Identifier,curVIB[i]->varName.TID);
		for(j=0; (j*4)<((curVIB[i]->varBlkNum)*(pstBoxInfo->uwBlkSize)); j++)
		{
	        p_buf[i][j] = (i+1)*j+9;
			dprintf("5. Task2: write pbuf[%d][%d] 0x%x = %d\r\n", i,j, &p_buf[i][j], (i+1)*j+9);
		}
	}
    LOS_TaskDelay(500);
	for(i=0; i<2; i++)
	{	
        p_buf[i]=curVIB[i]->addrStart;
        EXMC_PCRAM_BufferRead(Temp_Identifier,curVIB[i]->varName.Identifier,8);
        dprintf("5. Task2: read '%s(TID is %d)':\r\n", Temp_Identifier,curVIB[i]->varName.TID);
		for(j=0; (j*4)<((curVIB[i]->varBlkNum)*(pstBoxInfo->uwBlkSize)); j++)
		{
			dprintf("5. Task2: read pbuf[%d][%d] 0x%x = %d\r\n", i,j, &p_buf[i][j], p_buf[i][j]);
		}
	}
    dprintf("5. Task2 EXIT!\r\n");
}
UINT32 Example_pcramBOX_malloc_2task(VOID)
{
    UINT32 uwRet;
    printf("\r\n--------4.4 pcramBOX_malloc_2task test start!--------\r\n");
    UINT32 scpRet = LOS_OK;
    // UINT32 uwBoxSize = 0x10000UL;
    // UINT32 uwBlkSize = 0x1000;
    UINT32 uwBoxSize = PCRAM_BOX_HEAD_SIZE+64;
    UINT32 uwBlkSize = 7;
    TSK_INIT_PARAM_S stTask1;
    TSK_INIT_PARAM_S stTask2;

    /* lock task schedue */
    LOS_TaskLock();

    exmc_pcram_init();
    printf("3. exmc_pcram_init finish\r\n");
    // LOS_pcramboxClr(OS_PCRAM_START_ADDR, OS_PCRAM_START_ADDR, uwBoxSize);
    exmc_pcram_clear(OS_PCRAM_START_ADDR,PCRAM_BOX_HEAD_SIZE);
    exmc_pcram_clear(pcram_data_startaddr,uwBoxSize-PCRAM_BOX_HEAD_SIZE);
    printf("3. exmc_pcram_clear finish\r\n");
    printf("3. LOS_pcramboxInit start,uwBoxSize is %d Bytes, uwBlkSize is %d Bytes!\r\n",uwBoxSize,uwBlkSize);
    scpRet = LOS_pcramboxInit(OS_PCRAM_START_ADDR, uwBoxSize, uwBlkSize);
    if (scpRet != LOS_OK)
    {
        printf("3. pcrambox init error\r\n");
        return LOS_NOK;
    }
    else
    {
        printf("3. pcrambox init success!!\r\n");
        pstBoxInfo=OS_PCRAM_START_ADDR;
        printf("3. pstBoxInfo->uwBlkSize is %d Bytes,pstBoxInfo->uwBlkNum is %d!\r\n",pstBoxInfo->uwBlkSize,pstBoxInfo->uwBlkNum);
    }
    
    /* create task1 */
    memset(&stTask1, 0, sizeof(TSK_INIT_PARAM_S));
    stTask1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_pcramBOX_malloc_Task1;
    stTask1.pcName       = "PCRAMTsk1";
    stTask1.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    stTask1.usTaskPrio   = 4;
    uwRet = LOS_TaskCreate(&g_TestTaskID01, &stTask1);
    if (uwRet != LOS_OK)
    {
        dprintf("3. Example_pcramBOX_malloc_Task1 create failed . \r\n");
        return LOS_NOK;
    }
    else
    {
        dprintf("3. Example_pcramBOX_malloc_Task1 create success . \r\n");
    }

    /* create task2 */
    memset(&stTask2, 0, sizeof(TSK_INIT_PARAM_S));
    stTask2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_pcramBOX_malloc_Task2;
    stTask2.pcName       = "PCRAMTsk2";
    stTask2.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    stTask2.usTaskPrio   = 5;
    uwRet = LOS_TaskCreate(&g_TestTaskID02, &stTask2);
    if (uwRet != LOS_OK)
    {
        dprintf("3. Example_pcramBOX_malloc_Task2 create failed . \r\n");
        return LOS_NOK;
    }
    else
    {
        dprintf("3. Example_pcramBOX_malloc_Task2 create success . \r\n");
    }

    /* unlock task schedue */
    LOS_TaskUnlock();
    LOS_TaskDelay(4000);
    LOS_TaskDelete(g_TestTaskID01);
    LOS_TaskDelete(g_TestTaskID02);
    printf("3. pcramBOX_malloc_2task test success!\r\n");
}

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */
